package love.simbot.example.listen.listenServer;

import catcode.CatCodeUtil;
import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import love.forte.simbot.api.message.MessageContent;
import love.forte.simbot.api.message.events.MessageGet;
import love.forte.simbot.api.message.results.GroupList;
import love.forte.simbot.api.sender.Getter;
import love.forte.simbot.api.sender.Sender;
import love.simbot.example.constant.Constant;
import love.simbot.example.entity.Image.ImageData;
import love.simbot.example.entity.baidu.TranslationMapper;
import love.simbot.example.entity.baidu.TranslationResult;
import love.simbot.example.entity.bilibili.VideoData;
import love.simbot.example.entity.bilibili.VideoResult;
import love.simbot.example.entity.chatRobot.MoliChatRobot;
import love.simbot.example.entity.epidemic.LocationMessage;
import love.simbot.example.entity.wangyi.newSong.QQSongResult;
import love.simbot.example.entity.wangyi.newSong.WangYiSongResult;
import love.simbot.example.entity.wangyi.search.QQResult;
import love.simbot.example.entity.wangyi.search.SearchResult;
import love.simbot.example.utils.baidu.TransApi;
import love.simbot.example.utils.bilibili.BiliBiliUtils;
import love.simbot.example.utils.chatRobot.RobotUtils;
import love.simbot.example.utils.epidemic.EpidemicHttpUtils;
import love.simbot.example.utils.image.ImageUtils;
import love.simbot.example.utils.wangyi.MusicUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

public abstract class ListenerService {


    // 核心线程数为20的定时任务的线程池
    public static  final ScheduledExecutorService schedule =
            Executors.newScheduledThreadPool(30);

    // 音乐表单
    public static final ConcurrentHashMap<Long, HashMap<Integer,Long>> musicList =
            new ConcurrentHashMap<>();


    // 指令集(这里不用指令集存储下上一次对下一次指令有影响的指令也可以使用监听器的优先级来搞定)
    public static final  ConcurrentHashMap<Long,String> codeMap =
            new ConcurrentHashMap<>();

    // 定时任务
    public static final ConcurrentHashMap<Long, ScheduledFuture> timeTaskMap =
            new ConcurrentHashMap<>();

    // 视频集合
    public static final  ConcurrentHashMap<String,List<VideoData>> videoMap =
            new ConcurrentHashMap<>();

    // 群列表
    public static final ArrayList<String> groups = new ArrayList<>();




    // 百度翻译的调用
    public static void translationLanguage(String message, MessageGet getter, Sender sender){
        String[] params = message.split("^[A-Z] ");

        if(params == null || params.length < 2){
            sender.sendPrivateMsg(getter,"您的参数格式有问题哦！Miku Miku~~");
            return;
        }

        TransApi transApi = new TransApi(Constant.BaiDu_APPID,Constant.BaiDu_SECRETKEY);
        String transResult = transApi.getTransResult(params[1], "auto", "zh");

        if(transResult.contains("error_code")){
            sender.sendPrivateMsg(getter,"对不起,Miku现在还翻译不了！！！");
            return;
        }


        // 将翻译的Json串进行转换
        ObjectMapper om = new ObjectMapper();
        TranslationResult translationResult = null;
        try {
            translationResult  = om.readValue(transResult, TranslationResult.class);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }

        List<TranslationMapper> trans_result = translationResult.getTrans_result();

        StringBuffer buffer = new StringBuffer();
        for (TranslationMapper translationMapper : trans_result) {
            buffer.append(translationMapper.getSrc());
            buffer.append("：");
            buffer.append("\n");
            buffer.append(translationMapper.getDst());
        }

        // 翻译功能
        sender.sendPrivateMsg(getter, buffer.toString());

    }


    // 搜索音乐
    public static void searchMusic(String message,
                            Sender sender,MessageGet getter)  {
        // 1.进行消息切割
        String[] params = message.split("^[A-Z] ");


        if(params == null || params.length < 2 || params.length > 2){
            sender.sendPrivateMsg(getter,"主人,您的输入方式有问题呢!");
            return;
        }

        SearchResult searchResult = MusicUtils.SearchMusic(params[1], 5);
        QQResult qqResult = null;
        try {
            qqResult = MusicUtils.getQQMusicInfo(params[1]);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        if (searchResult == null || qqResult == null){
            sender.sendPrivateMsg(getter,"对不起 Miku正在休息中~~ 请主人之后再操作~~");
            return;
        }

        StringBuffer buffer = new StringBuffer();

        HashMap<Integer,Long> ids = new HashMap<>();

        buffer.append("请选择要播放的歌曲:\n");
        // 网易音乐
        buffer.append("======== 网易音乐 ========\n");
        for (int i = 0; i < searchResult.getResult().getSongs().size(); i++) {
            buffer.append(i+1+". ");
            buffer.append(searchResult.getResult().getSongs().get(i).getName()+"\t");
            buffer.append(searchResult.getResult().getSongs().get(i).getArtists().get(0).getName()+"\n");
            ids.put(i+1,searchResult.getResult().getSongs().get(i).getId());
        }
        buffer.append("======== QQ音乐 ========\n");
        for (int i = 0; i < qqResult.getData().size() && i < 5; i++) {
            buffer.append(i+6+". ");
            buffer.append(qqResult.getData().get(i).getSong()+"\t");
            buffer.append(qqResult.getData().get(i).getSingers()+"\n");
            ids.put(i+5,Long.valueOf(i));
        }

        musicList.put(getter.getAccountInfo().getAccountCodeNumber(),ids);
        // 将接下来要执行的指令集存储到ConcurrentHashMap中
        codeMap.put(getter.getAccountInfo().getAccountCodeNumber(),"B,"+params[1]);

        sender.sendPrivateMsg(getter,buffer.toString());
    }


    // 分享音乐
    public static void shareMusic(Sender sender,MessageGet messageGet){


        MessageContent msgContent = messageGet.getMsgContent();
        String msg = messageGet.getMsg();
        // 只有当你选择歌曲成功之后才会进行删除
        // 将指令码清除
        String searchMusic = codeMap.get(messageGet.getAccountInfo().getAccountCodeNumber());
        codeMap.remove(messageGet.getAccountInfo().getAccountCodeNumber());

        if (!msg.matches("^[0-9]")){
            sender.sendPrivateMsg(messageGet,"主人,请选择歌曲的序号呢!");
            return;
        }


        HashMap<Integer, Long> ids =
                musicList.get(messageGet.getAccountInfo().getAccountCodeNumber());
        String sharCat = null;

        Integer index = Integer.valueOf(msg);

        Long id = ids.get(index);
        // 网易搜索歌曲
        if(index <= 5) {
            WangYiSongResult musicInfo = null;
            try {
                musicInfo = MusicUtils.getMusicInfo(id);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }

            if (musicInfo == null || musicInfo.getMusicLink() == null) {
                sender.sendPrivateMsg(messageGet, "对不起,Miku找不到该歌曲,呜呜呜");
                return;
            }


            // 1.1.使用猫猫码来分享音乐
            CatCodeUtil catCodeUtil = CatCodeUtil.getInstance();
            sharCat = catCodeUtil.getStringCodeBuilder("music", false)
                    .key("type")
                    .value("neteaseCloud")
                    .key("musicUrl")
                    .value(musicInfo.getMusicLink())
                    .key("picture")
                    .value(musicInfo.getPicture())
                    .key("title")
                    .value(musicInfo.getSong())
                    .build();
        }
        // QQ音乐来搜索歌曲
        if(index > 5){
            String[] params = searchMusic.split(",");

            QQSongResult qqMusic = null;
            try {
                qqMusic = MusicUtils.getQQMusic(index, params[1]);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }

            if (qqMusic == null || qqMusic.getData().getUrl() == null) {
                sender.sendPrivateMsg(messageGet, "对不起,Miku找不到该歌曲,呜呜呜");
                return;
            }

            // 1.1.使用猫猫码来分享音乐
            CatCodeUtil catCodeUtil = CatCodeUtil.getInstance();
            sharCat = catCodeUtil.getStringCodeBuilder("music", false)
                    .key("type")
                    .value("QQ")
                    .key("musicUrl")
                    .value(qqMusic.getData().getMusic())
                    .key("picture")
                    .value(qqMusic.getData().getPicture())
                    .key("title")
                    .value(qqMusic.getData().getSong())
                    .build();
        }

        sender.sendPrivateMsg(messageGet,sharCat);
    }


    // 定时提醒的方法
    public static void regularlyRemind(MessageGet getter, Sender sender) {
        String msg = getter.getMsgContent().getMsg();
        String[] remain = msg.split(" ");
        String time = remain[1];
        // 进行格式判断
        if (remain == null || remain.length < 3 ||
                remain.length > 3 ||
                !time.matches("^[0-9]*$") ||
                remain[2].length() > 100) {
            sender.sendPrivateMsg(getter, "您输入格式有问题呢！");
            return;
        }
        // 设置定时任务,每间隔多少时间执行一次
        try {
            ScheduledFuture<?> scheduledFuture = schedule.
                    scheduleAtFixedRate(
                            ()->{
                                sender.sendPrivateMsg(getter,remain[2]);
                                // 这里测试使用秒钟,正式使用使用分钟
                            }, Long.valueOf(time), 5, TimeUnit.MINUTES);
            //使用concurrentHashMap存储
            timeTaskMap.put(getter.getAccountInfo().getAccountCodeNumber(),scheduledFuture);
        }catch(Exception e){
            // 出现异常的话,直接结束任务
            e.printStackTrace();
            schedule.shutdown();
        }

        sender.sendPrivateMsg(getter,"(注意:后面加入的定时提醒会覆盖前面的)已经开启定时提醒,取消的话请输入:cancel");
    }


    // 取消定时提醒
    public static void cancelTimeTask(long account, Sender sender) {
        ScheduledFuture<?> timerTask = timeTaskMap.get(account);
        // 取消任务
        timerTask.cancel(true);
        // 防止内存泄露(这里其实也可以给定时任务搞一个虚引用,这样就一定会被GC回收)
        timeTaskMap.remove(account);
        sender.sendPrivateMsg(account,"定时提醒已取消");
    }


    // 获取疫情的信息
    public  static void epidmicGet(Sender sender,MessageGet getter){
        String message = getter.getMsgContent().getMsg();
        // 1.进行消息切割
        String[] params = message.split("^[A-Z] ");

        if(params == null || params.length < 2 || params.length > 2){
            sender.sendPrivateMsg(getter,"主人,您的输入方式有问题呢!");
            return;
        }

        // 获取疫情的信息
        LocationMessage epidemicOfCity = EpidemicHttpUtils.getEpidemicOfCity(params[1]);

        StringBuffer buffer = new StringBuffer();

        buffer.append("=================\n");
        buffer.append("城市:"+epidemicOfCity.getData().getName()+"\n");
        buffer.append("更新时间:"+epidemicOfCity.getData().getTime()+"\n");
        buffer.append("总确诊数:"+epidemicOfCity.getData().getTotal()+"\n");
        buffer.append("疑似确诊:"+epidemicOfCity.getData().getSuspected()+"\n");
        buffer.append("累计死亡:"+epidemicOfCity.getData().getDeath()+"\n");
        buffer.append("累计死亡:"+epidemicOfCity.getData().getDeath()+"\n");
        buffer.append("累计治愈:"+epidemicOfCity.getData().getCure()+"\n");
        buffer.append("累计新增:"+epidemicOfCity.getData().getTotaladd()+"\n");
        buffer.append("现有确诊:"+epidemicOfCity.getData().getEcon()+"\n");
        buffer.append("现有无症状:"+epidemicOfCity.getData().getAsymptom()+"\n");
        buffer.append("=================");

        sender.sendPrivateMsg(getter,buffer.toString());
    }


    // 聊天机器人的调用
    public static void chatModeStart(Sender sender,MessageGet getter){
        sender.sendPrivateMsg(getter,"聊天模式开启,关闭请输入 exit");
        codeMap.put(getter.getAccountInfo().getAccountCodeNumber(),"D");
    }


    public static void chatMessageGet(Sender sender, MessageGet getter){

        String content = getter.getMsgContent().getMsg();
        String from = getter.getAccountInfo().getAccountCode();
        String fromName = getter.getAccountInfo().getAccountNickname();
        MoliChatRobot chatContent = RobotUtils.getChatContent(content, from, fromName, from, fromName, 1);
        sender.sendPrivateMsg(getter,chatContent.getData().get(0).getContent());
        /*ChatRobot chatMessage = ChatRobotUtils.getChatMessage(getter.getMsgContent().getMsg());
        sender.sendPrivateMsg(getter,chatMessage.getText());*/
    }


    // bilibili视频分享
    public static void searchBiliBiliVideo(Sender sender, MessageGet getter) {

        String msg = getter.getMsgContent().getMsg();

        String[] videoParams = msg.split(" ");

        if(videoParams.length != 2){
            sender.sendPrivateMsg(getter,"输入的格式有问题!");
            return;
        }

        VideoResult video = null;

        try {
            video = BiliBiliUtils.getVideo(StrUtil.cleanBlank(videoParams[1]));
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }

        if(video.getData() == null || video.getData().size() == 0){
            sender.sendPrivateMsg(getter,"对不起没有找到对应的视频");
            return;
        }

        videoMap.put(getter.getAccountInfo().getAccountCode(),video.getData());
        codeMap.put(getter.getAccountInfo().getAccountCodeNumber(),"H");

        StringBuffer buffer = new StringBuffer();
        buffer.append("====== 视频列表 ======\n");
        for (int i = 0; i < video.getData().size() && i <= 5; i++) {
            buffer.append(i+1+"."+video.getData().get(i).getName()+"\n");
        }
        buffer.append("==================");
        sender.sendPrivateMsg(getter,buffer.toString());
    }


    public static void shareBiliBiliVideo(Sender sender, MessageGet getter){
        MessageContent msgContent = getter.getMsgContent();
        String msg = getter.getMsg();
        // 将指令码清除
        codeMap.remove(getter.getAccountInfo().getAccountCodeNumber());

        if (!msg.matches("^[0-9]$")){
            sender.sendPrivateMsg(getter,"主人,请选择视频的序号呢!");
            return;
        }

        int position =  Integer.valueOf(msg)-1;
        List<VideoData> videoData = videoMap.get(getter.getAccountInfo().getAccountCode());
        if(position < 0){
            sender.sendPrivateMsg(getter,"主人,视频的序号不能小于1哦!");
            return;
        }
        VideoData video = videoData.get(position);


        CatCodeUtil catCodeUtil = CatCodeUtil.getInstance();
        String sharCat = catCodeUtil.getStringCodeBuilder("share", false)
                .key("title")
                .value(video.getName())
                .key("coverUrl")
                .value(video.getImg())
                .key("url")
                .value(video.getBrief())
                .build();

        sender.sendPrivateMsg(getter,sharCat);
    }


    // 代言模式
    public static void startRepersentSepeakMode(MessageGet getter, Sender sender, Getter get) {
        if(!getter.getAccountInfo().getAccountCode().equals("2019466881") && !getter.getAccountInfo().getAccountCode().equals("3186113904")){
            return;
        }
        // 1.获取加入的群列表
        GroupList groupList = get.getGroupList();
        StringBuffer buffer = new StringBuffer();

        AtomicInteger i = new AtomicInteger();
        groupList.forEach((v) ->{
            groups.add(v.getGroupCode());
            buffer.append(i.getAndIncrement()+1+"."+v.getGroupCode()+"\n");
        });
        sender.sendPrivateMsg(getter,buffer.toString());
        codeMap.put(getter.getAccountInfo().getAccountCodeNumber(),"I");
    }

    public static void repersentSpeak(Sender sender, MessageGet messageGet) {
        String msg = messageGet.getMsgContent().getMsg();
        if (!msg.matches("^[0-9]")){
            sender.sendPrivateMsg(messageGet,"主人,请选择代言的群号!");
            return;
        }

        Integer index = Integer.valueOf(msg);
        String groupCode = groups.get(index-1);

        GroupService.groupRepresent.put(messageGet.getAccountInfo().getAccountCode(),groupCode);

        groups.clear();
        codeMap.remove(messageGet.getAccountInfo().getAccountCodeNumber());

        sender.sendPrivateMsg(messageGet,"已开启代理聊天模式,关闭请输入getOut");
    }


    // 每日一图
    public static void sendImage(MessageGet getter,Sender sender){
        ImageData image = ImageUtils.getImage();
        CatCodeUtil instance = CatCodeUtil.INSTANCE;
        String build = instance.getStringCodeBuilder("image", false)
                .key("url").value(image.getImgurl()).build();
        sender.sendPrivateMsg(getter,build);
    }

}
